package com.captjack.validator.aspect;

import com.captjack.validator.Result;
import com.captjack.validator.annotation.BaseParamValidator;
import com.captjack.validator.handler.ParamValidatorHandler;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.validation.ConstraintViolation;
import java.lang.reflect.Method;
import java.util.Set;

/**
 * 参数校验切面类
 *
 * @author Jack Sparrow
 * @version 1.0.0
 * @date 2018/5/26 21:22
 * package com.captjack.wechat.validator.aspect
 */
@Configuration
@Aspect
public class BaseParamValidatorAspect extends AbstractValidator {

    /**
     * 校验器
     */
    private final ParamValidatorHandler paramValidatorHandler;

    /**
     * @param proceedingJoinPoint 切面对象
     * @return result
     */
    @Around(value = "@annotation(com.captjack.validator.annotation.BaseParamValidator)")
    Object baseValidatorAround(ProceedingJoinPoint proceedingJoinPoint) {
        try {
            // 获取标注注解
            BaseParamValidator baseParamValidator = getMethodAnnotation(proceedingJoinPoint, BaseParamValidator.class);
            // 获得切入目标对象
            Object target = proceedingJoinPoint.getThis();
            // 获得切入方法参数
            Object[] args = proceedingJoinPoint.getArgs();
            // 获得切入的方法
            Method method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod();
            // 校验基本数据类型方法参数
            Set<ConstraintViolation<Object>> validResult = paramValidatorHandler.validMethodParams(target, method, args, baseParamValidator.isFast());
            // 快速模式处理
            if (validResult.size() > 0) {
                return renderValidatorResult(validResult);
            }
            return proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return Result.SERVER_EXCEPTION;
    }

    @Autowired
    public BaseParamValidatorAspect(ParamValidatorHandler paramValidatorHandler) {
        this.paramValidatorHandler = paramValidatorHandler;
    }

}
